package com.office.web.controller.file.controller;

import com.office.common.core.controller.BaseController;
import com.office.common.core.domain.AjaxResult;
import com.office.common.utils.minio.MinioUtils;
import com.office.web.controller.file.server.FileUploadServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author: 柒月
 * @date: 2025/5/28 下午1:37
 * @version: 1.0
 */
@RestController
@RequestMapping("/file") // 统一路径前缀
public class FileUploadController extends BaseController {

    @Autowired
    private MinioUtils minioUtils; // 注入封装好的 MinIO 工具类

    @Resource
    private FileUploadServer fileUploadServer;

    /**
     * 文件上传接口
     *
     * @param file 前端上传的 MultipartFile 文件对象
     * @return 返回封装后的文件上传结果（原始名、存储名、访问链接）
     * @throws IOException 读取文件流失败时抛出异常
     * @throws Exception   其他通用异常（如 MinIO 操作异常）
     */
    @PostMapping("/upload")
    public MinioUtils.FileUploadResult upload(@RequestParam("file") MultipartFile file) throws IOException, Exception {
        String originalFilename = file.getOriginalFilename(); // 获取原始文件名
        logger.info("向 minio 上传文件 {}", originalFilename);
        long size = file.getSize(); // 文件大小
        String contentType = file.getContentType(); //文件 MIME 类型（如 image/jpeg）

        MinioUtils.FileUploadResult fileUploadResult;
        // 上传文件到minio
        // 使用 try-with-resources 自动关闭 InputStream
        try (InputStream inputStream = file.getInputStream()) {
            fileUploadResult = minioUtils.uploadWithResult(
                    originalFilename,
                    inputStream,
                    size,
                    contentType
            );
        }
        // 向数据库中添加数据并返回文件的id
        Long id = fileUploadServer.addFileUpload(
                fileUploadResult.getOriginalName(), // 原始文件名
                fileUploadResult.getStoredName(), // 存储在 mioin 中的文件名
                fileUploadResult.getUrl(), // 访问连接
                size, // 文件大小
                contentType);//  文件类型
        fileUploadResult.setId(id); // 设置文件id
        return fileUploadResult;
    }

    /**
     * 文件下载接口
     *
     * @param fileName 存储在 MinIO 中的文件名（UUID 格式）
     * @param response HttpServletResponse 用于向浏览器输出文件流
     * @throws Exception 下载过程中可能抛出的异常
     */
    @GetMapping("/download/{fileName}")
    public void download(@PathVariable String fileName, HttpServletResponse response) throws Exception {
        logger.info("下载文件{}",fileName);
        minioUtils.download(fileName, response); // 调用工具类进行下载操作
    }

    /**
     * 文件删除接口
     *
     * @param fileName 存储在 MinIO 中的文件名（UUID 格式）
     * @return 删除成功返回“删除成功”
     * @throws Exception 删除失败时抛出异常
     */
    @DeleteMapping("/delete/{fileName}")
    public AjaxResult delete(@PathVariable String fileName) throws Exception {
        logger.info("删除存储在 MinIO 中的文件 {}", fileName);
        minioUtils.delete(fileName); // 调用工具类删除指定文件
        return toAjax(fileUploadServer.deleteFileByName(fileName));// 删除文件库的文件
    }

    /**
     * 文件预览接口（生成访问 URL）
     *
     * @param fileName 存储在 MinIO 中的文件名（UUID 格式）
     * @return 返回完整的文件访问地址（可直接在浏览器打开）
     * @throws Exception 获取预览链接失败时抛出异常
     */
    @GetMapping("/preview/{fileName}")
    public String preview(@PathVariable String fileName) throws Exception {
        return minioUtils.getPreviewUrl(fileName); // 调用工具类生成预览链接
    }
}